package com.qiangqiang.resoldhouse.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.qiangqiang.resoldhouse.dto.AgentDTO;
import com.qiangqiang.resoldhouse.dto.CommentDTO;
import com.qiangqiang.resoldhouse.dto.PageDTO;
import com.qiangqiang.resoldhouse.entity.Agent;
import com.qiangqiang.resoldhouse.entity.Appointment;
import com.qiangqiang.resoldhouse.entity.Comment;
import com.qiangqiang.resoldhouse.mapper.CommentMapper;
import com.qiangqiang.resoldhouse.util.SnowflakeIdWorker;
import com.qiangqiang.resoldhouse.util.TimeFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: zqh
 * @date: 2018/8/15 9:20
 * @description:
 */
@Service
public class CommentService {

    @Autowired
    private CommentMapper mapper;

    @Autowired
    private AgentService agentService;

    @Autowired
    private AppointmentService appointmentService;


    public Boolean addComment(Comment comment){
        comment.setCommentId(new SnowflakeIdWorker(6,1).nextId());
        comment.setCommentTime(Instant.now().toEpochMilli());

        Appointment appointment = appointmentService.findAppointmentById(comment.getAppointmentId());
        comment.setAgentId(appointment.getAgentId());

        appointment.setCommentId(comment.getCommentId());
        appointmentService.updateAppointment(appointment);

        Boolean result = mapper.insert(comment) > 0;

        updateAgentStar(comment);
        return result;
    }

    //添加评论后，经纪人的星级信息会发生改变，需要重新计算
    public void updateAgentStar(Comment newComment){
        Long agentId = newComment.getAgentId();
        Agent agent = agentService.findAgentById(agentId);
        //取得所有的评论数，新的平均分 =（平均分*（评论数-1) + 新的分数）/（评论数）
        Integer sum = mapper.selectCount(new EntityWrapper<Comment>().eq("agent_id", agentId));
        Double newRank = (agent.getRank() * (sum - 1) + newComment.getStar() ) / sum;
        agent.setRank(newRank);
        agentService.updateAgent(agent);
    }

    //根据经纪人查看相关的评论，分页
    public PageDTO<CommentDTO> findCommentsByAgentId(Integer pageNum, Long agentId){
        PageDTO<CommentDTO> pageDTO = new PageDTO<>();
        Page<CommentDTO> page = new Page<>(pageNum,5);
        List<CommentDTO> result =  mapper.selectPage(page,
                new EntityWrapper<Comment>()
                        .eq("agent_id", agentId)
                        .orderBy("comment_time", false))
                .stream()
                .map(this::beanToDTO).collect(Collectors.toList());
        pageDTO.setPage(page);
        pageDTO.setResult(result);
        return pageDTO;
    }

    //根据用户id查询相关的评论,分页
    public PageDTO<CommentDTO> findCommentsByUserId(Integer pageNum, Long userId){
        PageDTO<CommentDTO> pageDTO = new PageDTO<>();
        Page<CommentDTO> page = new Page<>(pageNum,5);
        List<CommentDTO> result =  mapper.selectPage(page, new EntityWrapper<Comment>().eq("user_id", userId)).stream()
                .map(this::beanToDTO).collect(Collectors.toList());
        pageDTO.setPage(page);
        pageDTO.setResult(result);
        return pageDTO;
    }

    //一次预约看房只能评论一次，所以应该只会找到一个评论或者无评论
    public CommentDTO findCommentByAppointmentId(Long appointmentId){
        List<CommentDTO> list =  mapper.selectList(new EntityWrapper<Comment>().eq("appointment_id", appointmentId))
                .stream().map(this::beanToDTO).collect(Collectors.toList());
        if(list == null || list.get(0) == null) return null;
        else return list.get(0);
    }

    public CommentDTO findCommentByCommentId(Long commentId){
        Comment comment = mapper.selectById(commentId);
        return beanToDTO(comment);
    }

    public CommentDTO beanToDTO(Comment comment){
        CommentDTO dto = new CommentDTO();
        BeanUtils.copyProperties(comment, dto);
        dto.setCommentTime(TimeFormat.converTime(comment.getCommentTime()));
        return dto;
    }
}
